home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 23 code / ProjectDrag 1.1b4 / Sources / ProjectDrag Sources / PDUtilities.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-07  |  10.0 KB  |  418 lines  |  [TEXT/MPS ]

  1. /* PDUtilities.c: Utility routines for ProjectDrag
  2.  *
  3.  * A set of applets for drag and drop source control by Tim Maroney.
  4.  * See develop, issue 23 for details.
  5.  *
  6.  * Built on DropShell by Leonard Rosenthol, Stephan Somogyi, and Marshall Clow,
  7.  * and using the MoreFiles utilities by Jim Luther.
  8.  *
  9.  * This software is free, but don't modify and redistribute it without
  10.  * changing the status window to indicate your name and your changes!
  11.  */
  12.  
  13. #include <Errors.h>
  14. #include <Folders.h>
  15. #include <Resources.h>
  16. #include <Script.h>
  17. #include <Dialogs.h>
  18. #include <ToolUtils.h>
  19.  
  20. #include "PDUtilities.h"
  21. #include "MoreFilesExtras.h"
  22. #include "DSUtils.h"
  23.  
  24.  
  25. /* utility routine to find (and create if necesssary) the ProjectDrag
  26.  * Preferences folder inside the System Folder's Preferences folder
  27.  */
  28.  
  29. OSErr FindPreferencesFolder(short *vRefNum, long *folderID)
  30. {
  31.     OSErr err = noErr;
  32.     FSSpec ourFolder;
  33.     Boolean isFolder;
  34.     
  35.     err = FindFolder (kOnSystemDisk, kPreferencesFolderType, true, &ourFolder.vRefNum, &ourFolder.parID);
  36.     if (err != noErr)
  37.         return err;
  38.     GetIndString(ourFolder.name, kProjectDragStrings, kPrefsFolderName);
  39.     err = DirIDFromFSSpec(&ourFolder, folderID, &isFolder);
  40.     if (err == dirNFErr || err == fnfErr)
  41.         err = FSpDirCreate(&ourFolder, smSystemScript, folderID);
  42.     else if (!isFolder)
  43.         err = dirNFErr; /* isn't there an isAFileErr? */
  44.     if (err == noErr)
  45.         *vRefNum = ourFolder.vRefNum;
  46.     return err;
  47. }
  48.  
  49.  
  50. void AppendString(unsigned char *original, unsigned char *append)
  51.     // append one Pascal string to another
  52. {
  53.     int length;
  54.     if (original == 0 || append == 0) return;
  55.     length = append[0];
  56.     if (original[0] + length > 255)
  57.         length = 255 - original[0];
  58.     if (length == 0) return;
  59.     BlockMove(append + 1, original + original[0] + 1, length);
  60.     original[0] += length;
  61. }
  62.  
  63.  
  64. OSErr ProcessFileOrFolder(FSSpec *spec, void (*doFile)(FSSpec *spec, Boolean doingFolder),
  65.                          OSErr (*doFolder)(short vRefNum, long folderID,
  66.                                            void (*doFile)(FSSpec *spec, Boolean doingFolder)))
  67. {
  68.     if (spec->name[0] == 0)
  69.     {
  70.         return (*doFolder)(spec->vRefNum, spec->parID, doFile);
  71.     }
  72.     else
  73.     {
  74.         CInfoPBRec pb;
  75.         
  76.         pb.hFileInfo.ioVRefNum = spec->vRefNum;
  77.         pb.hFileInfo.ioDirID = spec->parID;
  78.         pb.hFileInfo.ioNamePtr = spec->name;
  79.         pb.hFileInfo.ioFDirIndex = (spec->name[0] == 0) ? -1 : 0;
  80.         PBGetCatInfoSync(&pb);
  81.         if (pb.hFileInfo.ioResult != noErr) return pb.hFileInfo.ioResult;
  82.         if ((pb.hFileInfo.ioFlAttrib & 0x10) == 0)
  83.             (*doFile)(spec, false);
  84.         else
  85.             (*doFolder)(spec->vRefNum, pb.dirInfo.ioDrDirID, doFile);
  86.     }
  87.     return noErr;
  88. }
  89.  
  90.  
  91. OSErr ProcessFolder(short vRefNum, long folderID, void (*doFile)(FSSpec *spec, Boolean doingFolder))
  92. {
  93.     CInfoPBRec pb;
  94.     OSErr err = noErr;
  95.     
  96.     /* for all the items in the folder */
  97.     for (pb.hFileInfo.ioFDirIndex = 1; err == noErr && !gDone; pb.hFileInfo.ioFDirIndex++)
  98.     {
  99.         FSSpec spec;
  100.         Boolean isFile;
  101.  
  102.         spec.name[0] = 0;
  103.         pb.hFileInfo.ioNamePtr = spec.name;
  104.         pb.hFileInfo.ioVRefNum = vRefNum;
  105.         pb.hFileInfo.ioDirID = folderID;
  106.         err = PBGetCatInfoSync(&pb);
  107.         if (err != noErr) break;
  108.         
  109.         isFile = ((pb.hFileInfo.ioFlAttrib & 0x10) == 0);
  110.         
  111.         if (isFile)
  112.         {
  113.             spec.vRefNum = vRefNum;
  114.             spec.parID = folderID;
  115.             (*doFile)(&spec, true);
  116.         }
  117.         else
  118.         {
  119.             ProcessFolder(vRefNum, pb.dirInfo.ioDrDirID, doFile);
  120.         }
  121.     }
  122.     if (err == fnfErr)
  123.         err = noErr; /* end of loop */
  124.     return err;
  125. }
  126.  
  127.  
  128. OSErr MakeFullPathName(FSSpec *spec, Str255 fullPathName)
  129. {
  130.     CInfoPBRec pb;
  131.     OSErr err = noErr;
  132.     short vRefNum = spec->vRefNum;
  133.     long folderID = spec->parID;
  134.     
  135.     if (spec->name[0] == 0)
  136.         fullPathName[0] = 0;
  137.     else
  138.         BlockMove(spec->name, fullPathName, spec->name[0] + 1);
  139.     
  140.     do
  141.     {
  142.         Str31 folderName;
  143.  
  144.         folderName[0] = 0;
  145.         pb.hFileInfo.ioNamePtr = folderName;
  146.         pb.hFileInfo.ioVRefNum = vRefNum;
  147.         pb.hFileInfo.ioDirID = folderID;
  148.         pb.hFileInfo.ioFDirIndex = -1;
  149.         err = PBGetCatInfoSync(&pb);
  150.         if (err == noErr)
  151.         {
  152.             if (fullPathName[0] > 0)
  153.                 BlockMove(fullPathName + 1, fullPathName + 2 + folderName[0], fullPathName[0]);
  154.             BlockMove(folderName + 1, fullPathName + 1, folderName[0]);
  155.             fullPathName[folderName[0] + 1] = ':';
  156.             fullPathName[0] += folderName[0] + 1;
  157.             folderID = pb.dirInfo.ioDrParID;
  158.         }
  159.     } while (err == noErr && folderID != fsRtParID);
  160.     return err;
  161. }
  162.  
  163.  
  164. OSErr ExtractCKID(FSSpec *file, CKIDHandle *theCKID)
  165. {
  166.     /* open the resource file */
  167.     short refNum = FSpOpenResFile(file, fsRdPerm);
  168.     if (refNum < 0)
  169.         return ResError();
  170.     
  171.     /* get the CKID from it and clone it */
  172.     *theCKID = (CKIDHandle) Get1IndResource('ckid', 1);
  173.     if (*theCKID == NULL)
  174.     {
  175.         CloseResFile(refNum);
  176.         return resNotFound;
  177.     }
  178.     DetachResource((Handle)*theCKID);
  179.     
  180.     /* close the resource file */
  181.     CloseResFile(refNum);
  182.     return noErr;
  183. }
  184.  
  185. static Boolean IsCommandKey(EventRecord *event)
  186. {
  187.     return (event->what == keyDown) && ((event->modifiers & cmdKey) != 0);
  188. }
  189.  
  190. pascal Boolean ProjectDragIdleProc(EventRecord *theEvent, long *sleepTime, RgnHandle *mouseRgn)
  191. {
  192.     if (theEvent->what == nullEvent)
  193.     {
  194.         *mouseRgn = NULL;
  195.         *sleepTime = 10;
  196.     }
  197.     else if (!IsCommandKey(theEvent) && IsDialogEvent(theEvent))
  198.     {
  199.         DialogPtr dialog;
  200.         short itemHit;
  201.         
  202.         DialogSelect(theEvent, &dialog, &itemHit);
  203.     }
  204.     return false;
  205. }
  206.  
  207.  
  208. short ReplaceString(Handle baseText, StringPtr key, StringPtr substitutionText)
  209. {
  210.     OSErr err = noErr;
  211.     Handle h = NULL;
  212.     
  213.     err = PtrToHand(substitutionText + 1, &h, substitutionText[0]);
  214.     if (err != noErr) return err;
  215.     err = ReplaceText(baseText, h, key);
  216.     DisposeHandle(h);
  217.     return err;
  218. }
  219.  
  220.  
  221. void ReplaceInIndString(StringPtr stringOut, short strListID, short strIndex,
  222.                         StringPtr param1, StringPtr param2,
  223.                         StringPtr param3, StringPtr param4)
  224. {
  225.     Handle h;
  226.     OSErr err;
  227.     
  228.     GetIndString(stringOut, strListID, strIndex);
  229.     err = PtrToHand(stringOut + 1, &h, stringOut[0]);
  230.     if (param1 != NULL)
  231.         err = ReplaceString(h, "\p<1>", param1);
  232.     else
  233.         err = ReplaceString(h, "\p<1>", "\p");
  234.     if (param2 != NULL)
  235.         err = ReplaceString(h, "\p<2>", param2);
  236.     else
  237.         err = ReplaceString(h, "\p<2>", "\p");
  238.     if (param3 != NULL)
  239.         err = ReplaceString(h, "\p<3>", param3);
  240.     else
  241.         err = ReplaceString(h, "\p<3>", "\p");
  242.     if (param4 != NULL)
  243.         err = ReplaceString(h, "\p<4>", param4);
  244.     else
  245.         err = ReplaceString(h, "\p<4>", "\p");
  246.     stringOut[0] = GetHandleSize(h);
  247.     BlockMoveData(*h, stringOut + 1, stringOut[0]);
  248.     DisposeHandle(h);
  249. }
  250.  
  251.  
  252. long LineSize(StringPtr theLine, long maxSize)
  253. {
  254.     long length;
  255.     for (length = 0; maxSize > 0; theLine++, maxSize--)
  256.     {
  257.         length++;
  258.         if (*theLine == '\n') break; /* after incrementing the length to include this */
  259.     }
  260.     return length;
  261. }
  262.  
  263.  
  264. Boolean MatchLineUntilChar(StringPtr line1, long len1, StringPtr line2, long len2, char untilChar)
  265. {
  266.     long i, j;
  267.         
  268.     for (i = j = 0; i < len1 && j < len2; )
  269.     {
  270.         if (untilChar != 0 && line2[j] == untilChar)
  271.             return true; /* we reached the stop character */
  272.             
  273.         if (line1[i] == '\n' || line2[j] == '\n')
  274.         {
  275.             /* if we reach the end of line on one, we must reach it on the other */
  276.             return line1[i] == '\n' && line2[j] == '\n';
  277.         }
  278.         else if (line1[i] == ' ' || line1[i] == '\t')
  279.         {
  280.             /* any amount of white space matches any other */
  281.             if (line2[j] != ' ' && line2[j] != '\t')
  282.                 return false;
  283.             i++, j++; /* we know these characters are blanks */
  284.             while (i < len1 && line1[i] == ' ' || line1[i] == '\t')
  285.                 i++;
  286.             while (j < len2 && line2[j] == ' ' || line2[j] == '\t')
  287.                 j++;
  288.         }
  289.         else if (line1[i] != line2[j])
  290.         {
  291.             return false;
  292.         }
  293.         else /* still matching, go on to next character */
  294.         {
  295.             i++, j++; /* this is here instead of in "for" because
  296.                        * these variables get changed internally
  297.                        */
  298.         }
  299.     }
  300.     
  301.     /* if we get here, all characters should have been exhausted (as am I);
  302.      * the only exception is that one may still have an unexhausted end of line...
  303.      */
  304.     return (len1 == i || (len1 == i + 1 && line1[i] == '\n'))
  305.             && (len2 == j || (len2 == j + 1 && line2[j] == '\n'));
  306. }
  307.  
  308.  
  309. Boolean MatchLine(StringPtr line1, long len1, StringPtr line2, long len2)
  310. {
  311.     return MatchLineUntilChar(line1, len1, line2, len2, 0);
  312. }
  313.  
  314.  
  315. OSErr GetFileData(FSSpec *file, Handle *fileData, short *refNum)
  316. {
  317.     OSErr err;
  318.     IOParam io;
  319.     long count;
  320.     
  321.     *fileData = NULL;
  322.     *refNum = -1;
  323.     
  324.     err = FSpOpenDF(file, fsRdWrPerm, refNum);
  325.     if (err != noErr) goto ErrorExit;
  326.     err = GetEOF(*refNum, &count);
  327.     if (err != noErr) goto ErrorExit;
  328.     *fileData = TempNewHandle(count, &err);
  329.     if (err != noErr) goto ErrorExit;
  330.     HLock(*fileData);
  331.     io.ioCompletion = NULL;
  332.     io.ioRefNum = *refNum;
  333.     io.ioBuffer = **fileData;
  334.     io.ioReqCount = count;
  335.     io.ioPosMode = fsFromStart;
  336.     io.ioPosOffset = 0;
  337.     PBReadAsync((ParmBlkPtr)&io);
  338.     while (io.ioResult == 1)
  339.     {
  340.         EventRecord event;
  341.         WaitNextEvent(everyEvent, &event, 10, NULL);
  342.     }
  343.     err = io.ioResult;
  344.     if (err != noErr) goto ErrorExit;
  345.     HUnlock(*fileData);
  346.     return noErr;
  347.  
  348. ErrorExit:
  349.     if (*refNum != -1)
  350.     {
  351.         FSClose(*refNum);
  352.         *refNum = -1;
  353.     }
  354.     if (*fileData != NULL)
  355.     {
  356.         DisposeHandle(*fileData);
  357.         *fileData = NULL;
  358.     }
  359.     return err;
  360. }
  361.  
  362.  
  363. OSErr WriteFileWithHeader(short refNum, Handle fileData, long startOffset, StringHandle header)
  364. {
  365.     OSErr err = noErr;
  366.     Byte state;
  367.     IOParam io;
  368.     
  369.     /* zero the file */
  370.     err = SetEOF(refNum, 0);
  371.     if (err != noErr) return err;
  372.     err = SetFPos(refNum, fsFromStart, 0);
  373.     if (err != noErr) return err;
  374.     
  375.     /* write out the header to the file */
  376.     if (header != NULL)
  377.     {
  378.         state = HGetState(header);
  379.         HLock(header);
  380.         io.ioCompletion = NULL;
  381.         io.ioRefNum = refNum;
  382.         io.ioBuffer = *header;
  383.         io.ioReqCount = GetHandleSize(header);
  384.         io.ioPosMode = fsFromStart;
  385.         io.ioPosOffset = 0;
  386.         PBWriteAsync((ParmBlkPtr)&io);
  387.         while (io.ioResult == 1)
  388.         {
  389.             EventRecord event;
  390.             WaitNextEvent(everyEvent, &event, 10, NULL);
  391.         }
  392.         err = io.ioResult;
  393.         HSetState(header, state);
  394.         if (err != noErr) return err;
  395.     }
  396.     
  397.     /* copy the data fork from the start offset to the file */
  398.     state = HGetState(fileData);
  399.     HLock(fileData);
  400.     io.ioCompletion = NULL;
  401.     io.ioRefNum = refNum;
  402.     io.ioBuffer = (*fileData) + startOffset;
  403.     io.ioReqCount = GetHandleSize(fileData) - startOffset;
  404.     io.ioPosMode = fsFromStart;
  405.     io.ioPosOffset = GetHandleSize(header);
  406.     PBWriteAsync((ParmBlkPtr)&io);
  407.     while (io.ioResult == 1)
  408.     {
  409.         EventRecord event;
  410.         WaitNextEvent(everyEvent, &event, 10, NULL);
  411.     }
  412.     err = io.ioResult;
  413.     HSetState(fileData, state);
  414.     if (err != noErr) return err;
  415.     
  416.     return noErr;
  417. }
  418.